package com.lyfy.sd.order.controller;

import com.google.common.collect.Lists;
import com.lyfy.sd.order.dao.entity.OrderItem;
import com.lyfy.sd.order.dao.entity.OrderMaster;
import com.lyfy.sd.order.dao.mapper.OrderItemMapper;
import com.lyfy.sd.order.dao.mapper.OrderMasterMapper;
import com.lyfy.sd.order.vo.RespVo;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;

import static com.lyfy.sd.order.constant.Constant.DEFAULT_CREATOR;
import static com.lyfy.sd.order.constant.Constant.DEFAULT_USER_ID;

/**
 * @author: 谢星星
 * @date: 2022/10/3 01:09
 * @description:
 */
@RestController
public class SdInsertController {

    @Resource
    private OrderMasterMapper orderMasterMapper;

    @Resource
    private OrderItemMapper orderItemMapper;


    /**
     * 场景：可以根据MurmurHash算法均匀路由到数据节点，兼容MyCat路由算法
     */
    @GetMapping(value = "/sd/insert", produces = MediaType.APPLICATION_JSON_VALUE)
    public RespVo insert() {
        Date now = new Date();
        for (int i = 0; i < 10; i++) {
            OrderMaster orderMaster = new OrderMaster();
            orderMaster.setOrderMasterId(RandomUtils.nextLong());
            orderMaster.setUserId(Long.valueOf(i));
            orderMaster.setCreateD(now);
            orderMaster.setUpdateD(now);
            orderMaster.setCreator(DEFAULT_CREATOR);
            orderMaster.setOrderStatus(1);
            orderMaster.setPayStatus(1);
            orderMaster.setUpdator(DEFAULT_CREATOR);
            orderMaster.setModifyD(now);
            orderMasterMapper.insert(orderMaster);
        }

        return RespVo.SUCCESS();
    }

    /**
     * 场景：同一个用户的数据路由到同一个库中，并支持事务
     *      插入数据时，数据不会落到从库中
     */
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    @GetMapping(value = "/sd/insert-tx", produces = MediaType.APPLICATION_JSON_VALUE)
    public RespVo insertTx() {
        Date now = new Date();
//        Long orderMasterId = RandomUtils.nextLong();
        Long orderMasterId = 1000L;
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setOrderMasterId(orderMasterId);
        orderMaster.setUserId(DEFAULT_USER_ID);
        orderMaster.setCreateD(now);
        orderMaster.setUpdateD(now);
        orderMaster.setCreator(DEFAULT_CREATOR);
        orderMaster.setOrderStatus(1);
        orderMaster.setPayStatus(1);
        orderMaster.setUpdator(DEFAULT_CREATOR);
        orderMaster.setModifyD(now);

        OrderItem orderItem1 = new OrderItem();
        orderItem1.setCreateD(now);
        orderItem1.setCreator(DEFAULT_CREATOR);
        orderItem1.setUpdateD(now);
        orderItem1.setUpdator(DEFAULT_CREATOR);
        orderItem1.setModifyD(now);
        orderItem1.setId(RandomUtils.nextLong());
        orderItem1.setOrderItemId(RandomUtils.nextLong());
        orderItem1.setUserId(DEFAULT_USER_ID);
        orderItem1.setOrderMasterId(orderMasterId);
        orderItem1.setPayAmt(100L);
        orderItem1.setPointAmt(10L);

        OrderItem orderItem2 = new OrderItem();
        orderItem2.setCreateD(now);
        orderItem2.setCreator(DEFAULT_CREATOR);
        orderItem2.setUpdateD(now);
        orderItem2.setUpdator(DEFAULT_CREATOR);
        orderItem2.setModifyD(now);
        orderItem2.setId(RandomUtils.nextLong());
        orderItem2.setOrderItemId(RandomUtils.nextLong());
        orderItem2.setUserId(DEFAULT_USER_ID);
        orderItem2.setOrderMasterId(orderMasterId);
        orderItem2.setPayAmt(100L);
        orderItem2.setPointAmt(10L);

        orderMasterMapper.insert(orderMaster);
        orderItemMapper.insertList(Lists.newArrayList(orderItem1, orderItem2));
        return RespVo.SUCCESS();
    }

    /**
     * 场景：同一个用户的数据路由到同一个库中，并支持事务
     */
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    @GetMapping(value = "/sd/insert-tx-ex", produces = MediaType.APPLICATION_JSON_VALUE)
    public RespVo insertTxEx() {
        Date now = new Date();
        Long orderMasterId = RandomUtils.nextLong();
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setOrderMasterId(orderMasterId);
        orderMaster.setUserId(DEFAULT_USER_ID);
        orderMaster.setCreateD(now);
        orderMaster.setUpdateD(now);
        orderMaster.setCreator(DEFAULT_CREATOR);
        orderMaster.setOrderStatus(1);
        orderMaster.setPayStatus(1);
        orderMaster.setUpdator(DEFAULT_CREATOR);
        orderMaster.setModifyD(now);

        OrderItem orderItem = new OrderItem();
        orderItem.setCreateD(now);
        orderItem.setCreator(DEFAULT_CREATOR);
        orderItem.setUpdateD(now);
        orderItem.setUpdator(DEFAULT_CREATOR);
        orderItem.setModifyD(now);
        orderItem.setId(RandomUtils.nextLong());
        orderItem.setOrderItemId(RandomUtils.nextLong());
        orderItem.setUserId(DEFAULT_USER_ID);
        orderItem.setOrderMasterId(orderMasterId);
        orderItem.setPayAmt(100L);
        orderItem.setPointAmt(10L);

        orderMasterMapper.insert(orderMaster);
        orderItemMapper.insert(orderItem);
        throw new RuntimeException("抛出一个异常，测试数据可以回滚。");
    }

}
